package com.fingard.dsp.bank.directbank.swiftpass01;

import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.RefundState;
import com.fingard.dsp.bank.directbank.bankInterface.IRecRefund;
import com.fingard.dsp.bank.directbank.swiftpass01.util.SignUtil;
import com.fingard.dsp.bank.reqrespobj.recrefund.ReqQryRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.ReqRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.RetAtsQryRecRefund;
import com.fingard.dsp.bank.reqrespobj.recrefund.RetAtsRecRefund;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;

import java.util.HashMap;

public class SwiftPass01RecRefund extends SwiftPass01Base implements IRecRefund {
    @Override
    public RetAtsRecRefund submitRecRefund(ReqRecRefund p_reqRef) throws Exception {
        RetAtsRecRefund retAts = new RetAtsRecRefund();
        retAts.oriRdSeq = p_reqRef.oriRdSeq;
        retAts.refundNo = p_reqRef.refundNo;

        try {
            ActSetItem actItem = this.getBankConfig().getActSetItem(p_reqRef.ownAct, "unifiedorder");
            if (actItem != null) {
                HashMap<String, String> mapParams = new HashMap<String, String>();

                mapParams.put("service", "unified.trade.refund");// 接口类型
                mapParams.put("version", "2.0");
                mapParams.put("charset", getCharset());
                mapParams.put("sign_type", "RSA_1_256");// 签名方式
                mapParams.put("mch_id", actItem.merchantId);
                mapParams.put("out_trade_no", p_reqRef.oriRdSeq);// 商户订单号
                mapParams.put("transaction_id", "");
                mapParams.put("out_refund_no", p_reqRef.refundNo);
                mapParams.put("total_fee", StringHelper.amountMultiply100(p_reqRef.totalAmt));
                mapParams.put("refund_fee", StringHelper.amountMultiply100(p_reqRef.amount));
                mapParams.put("attach", "");
                mapParams.put("op_user_id", actItem.merchantId);
                mapParams.put("refund_channel", "ORIGINAL");
                mapParams.put("nonce_str", get_nonce_str());
                mapParams.put("device_location", "");

                String refundKey = actItem.saltKeyMap.get("refund");
                WriteBankLogLn("退款密钥:" + refundKey);

                String signMsg = SignUtil.sign(mapParams, "RSA_1_256", refundKey);
                mapParams.put("sign", signMsg);

                String tmpXml = buildXml(mapParams);

                String[] tmpStrRet = sendToBank(tmpXml, "unifiedorder");

                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        retAts.respCode = "0";

                        String status = tmpBkReader.getFirstText("/xml/status");
                        String message = tmpBkReader.getFirstText("/xml/message");
                        if (status != null && "0".equals(status)) {
                            String result_code = tmpBkReader.getFirstText("/xml/result_code");
                            if ("0".equalsIgnoreCase(result_code)) {
                                retAts.refundState = RefundState.REFUND_PAYING;
                                retAts.originalCode = result_code;
                                retAts.originalInfo = message;
                                retAts.unifiedCode = "I4001";
                            } else {
                                retAts.refundState = RefundState.REFUND_FAIL;
                                String errCode = tmpBkReader.getFirstText("/xml/err_code");
                                String errMsg = tmpBkReader.getFirstText("/xml/err_msg");
                                retAts.originalCode = errCode;
                                retAts.originalInfo = errMsg;
                                retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", errCode);
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = message;
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                    }
                } else if (tmpStrRet[0].equals(ConnState.FAIL)) {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            } else {
                retAts.respCode = "0";
                retAts.respInfo = "未找到账号[" + p_reqRef.ownAct + "]商户配置信息!";
                retAts.refundState = RefundState.REFUND_FAIL;
                retAts.originalCode = "E9981";
                retAts.originalInfo = retAts.respInfo;
                retAts.unifiedCode = "E9981";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }

    @Override
    public RetAtsQryRecRefund queryRecRefund(ReqQryRecRefund p_reqQryRef) throws Exception {
        RetAtsQryRecRefund retAts = new RetAtsQryRecRefund();
        retAts.oriRdSeq = p_reqQryRef.oriRdSeq;
        retAts.refundNo = p_reqQryRef.refundNo;

        try {
            ActSetItem actItem = this.getBankConfig().getActSetItem(p_reqQryRef.ownAct, "unifiedorder");
            if (actItem != null) {
                HashMap<String, String> mapParams = new HashMap<String, String>();

                mapParams.put("service", "unified.trade.refundquery");
                mapParams.put("version", "2.0");
                mapParams.put("charset", getCharset());
                mapParams.put("sign_type", "RSA_1_256");
                mapParams.put("mch_id", actItem.merchantId);
                mapParams.put("out_trade_no", p_reqQryRef.oriRdSeq);
                mapParams.put("out_refund_no", p_reqQryRef.refundNo);
                mapParams.put("refund_id", "");

                String nonce_str = get_nonce_str();
                mapParams.put("nonce_str", nonce_str);

                String refundKey = actItem.saltKeyMap.get("refund");
                WriteBankLogLn("退款密钥:" + refundKey);

                String signMsg = SignUtil.sign(mapParams, "RSA_1_256", refundKey);
                mapParams.put("sign", signMsg);

                String tmpXml = buildXml(mapParams);

                String[] tmpStrRet = sendToBank(tmpXml, "unifiedorder");

                if (tmpStrRet[0].length() == 0) {
                    StringBuilder tmpSbMsg = new StringBuilder();
                    XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                    if (tmpBkReader != null) {
                        String status = tmpBkReader.getFirstText("/xml/status");
                        String message = tmpBkReader.getFirstText("/xml/message");
                        if (status != null && status.equals("0")) {
                            String result_code = tmpBkReader.getFirstText("/xml/result_code");
                            String err_code = tmpBkReader.getFirstText("/xml/err_code");
                            String err_msg = tmpBkReader.getFirstText("/xml/err_msg");
                            retAts.respCode = "0";
                            retAts.respInfo = message;
                            if (StringHelper.hasAnyChar(err_msg)) {
                                retAts.respInfo = err_msg;
                            }
                            if ("0".equalsIgnoreCase(result_code)) {
                                retAts.oriOppOrderNo = tmpBkReader.getFirstText("/xml/out_transaction_id");
                                retAts.oppRefundNo = tmpBkReader.getFirstText("/xml/refund_id_0");
                                retAts.refundChannel = tmpBkReader.getFirstText("/xml/refund_channel_0");

                                String refundState = tmpBkReader.getFirstText("/xml/refund_status_0");
                                if ("SUCCESS".equals(refundState)) {
                                    retAts.refundState = RefundState.REFUND_SUCCESS;
                                } else if ("REFUNDCLOSE".equals(refundState)) {
                                    retAts.refundState = RefundState.REFUND_CLOSED;
                                } else if ("PROCESSING".equals(refundState)) {
                                    retAts.refundState = RefundState.REFUND_PAYING;
                                } else {
                                    retAts.refundState = RefundState.REFUND_FAIL;
                                }
                                if (StringHelper.hasAnyChar(err_code)) {
                                    retAts.originalCode = err_code;
                                    retAts.originalInfo = err_msg;
                                    retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", err_code);
                                } else {
                                    retAts.originalCode = result_code;
                                    retAts.originalInfo = message;
                                    retAts.unifiedCode = getBankConfig().getMapValueByKey("recRefundMapping", refundState);
                                }
                            } else {
                                retAts.respCode = "-1";
                                if ("Refund not exists".equalsIgnoreCase(err_code)) {
                                    retAts.respCode = "0";
                                    retAts.refundState = RefundState.REFUND_FAIL;
                                    retAts.originalCode = err_code;
                                    retAts.originalInfo = err_msg;
                                    retAts.unifiedCode = "E1302";
                                }
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = message;
                        }
                    } else {
                        retAts.respCode = "-1";
                        retAts.respInfo = tmpSbMsg.toString();
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpStrRet[1];
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "未找到账号[" + p_reqQryRef.ownAct + "]商户配置信息!";
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return retAts;
    }
}